package work.base.jvm.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.LinkedList;
import java.util.List;

/**
 * 虚引用的实现
 * 虚引用的作用: 管理堆外内存 jvm的NIO就是虚引用的实现
 * GC监视 虚引用的队列 队列中有元素进来了 清理与之相关的堆外内存
 *
 */
public class PhantomReferenceTest {

    private static final List<Object> LIST = new LinkedList<>();

    /**
     * 虚引用队列
     */
    private static final ReferenceQueue<ReferenceEntity> QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {
        PhantomReference<ReferenceEntity> phantomReference = new PhantomReference(new ReferenceEntity(), QUEUE);

        // 虚引用的get是返回null
        System.out.println(phantomReference.get());

        new Thread(()-> {
            while(true) {
                LIST.add(new byte[1024*1024]);
                try{
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());
            }
        }).start();

        new Thread(()-> {
            while(true) {
                // 一旦虚引用被回收了 队列中就会接收到元素
                // jvm调小堆内存大小 可以明显看出虚引用的回收
                Reference<? extends ReferenceEntity> poll = QUEUE.poll();
                if(null != poll) {
                    System.out.println("----虚引用对象被JVM回收了----" + poll);
                }
            }
        }).start();

        try{
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }
}
